﻿using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Spi;
using Quartz.Util;
using System;

namespace NetCore.Common.Quartz
{
    /// <summary>
    /// The default JobFactory used by Quartz - simply calls
    /// <see cref="ObjectUtils.InstantiateType{T}" /> on the job class.
    /// </summary>
    public class SimpleJobFactory : IJobFactory
    {
        private readonly ILogger<SimpleJobFactory> _logger;

        public SimpleJobFactory(ILogger<SimpleJobFactory> logger)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger)); ; // <-添加此行;
        }

        /// <summary>
        /// Called by the scheduler at the time of the trigger firing, in order to
        /// produce a <see cref="IJob" /> instance on which to call Execute.
        /// </summary>

        public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
            IJobDetail jobDetail = bundle.JobDetail;
            Type jobType = jobDetail.JobType;
            try
            {
                //_logger.LogInformation($"Producing instance of Job '{jobDetail.Key}', class={jobType.FullName}");

                return ObjectUtils.InstantiateType<IJob>(jobType);
            }
            catch (Exception ex)
            {
                SchedulerException se = new SchedulerException($"Problem instantiating class '{jobDetail.JobType.FullName}'", ex);
                _logger.LogError(ex, ex.Message, $"Problem instantiating class '{jobDetail.JobType.FullName}'");
                throw se;
            }
        }

        /// <summary>
        /// Allows the job factory to destroy/cleanup the job if needed.
        /// No-op when using SimpleJobFactory.
        /// </summary>
        public virtual void ReturnJob(IJob job)
        {
            var disposable = job as IDisposable;
            disposable?.Dispose();
        }
    }
}